#include "hd44780.h"
#include <msp430g2231.h>

volatile unsigned int LCDPORT;

void LCD_Init(char port)
{
	switch(port)
	{
		case 1:
			P1DIR = 0xFF;
			LCDPORT = P1OUT;
			break;
		case 2:
			P2DIR = 0xFF;
			LCDPORT = P2OUT;
			break;
		case 3:
			P3DIR = 0xFF;
			LCDPORT = P3OUT;
			break;
		case 4:
			P4DIR = 0xFF;
			LCDPORT = P4OUT;
			break;
		case 5:
			P5DIR = 0xFF;
			LCDPORT = P5OUT;
			break;
	}
}

void delayms(int delay)
{
	int i, j;
	for(i = 0; i < delay; i++)
		for(j = 0; j < 95; j++);
}

void LCDwrite4bits(char data)
{
	LCDPORT &= ~(0xF);
	LCDPORT |= data;
	LCDPORT |= 0x01 << LCD_ENABLE;
	delayms(1);
	LCDPORT &= ~(0x01 << LCD_ENABLE);
}

void LCDwriteCommand(char command, char rs)
{
	// if we need RS high, do it now
	if(rs == RS_HIGH)
		LCDPORT |= 0x01 << LCD_RS;
	else
		LCDPORT &= ~(0x01 << LCD_RS);
	
	// send most significant 4 bits
	LCDwrite4bits((command & 0xF0) >> 4);
	
	// send least significant 4 bits
	LCDwrite4bits(command & 0x0F);
	
	// turn off the RS pin
	LCDPORT &= ~(0x01 << LCD_RS);
	
	delayms(4);
}


// Clear the display and return the cursor to the home position
void LCDclear(void)
{
	LCDwriteCommand(0x01, RS_LOW);
	delayms(2);
}

// Return the cursor to the home position
void LCDreturnHome(void)
{
	LCDwriteCommand(0x02, RS_LOW);
	delayms(2);
}

void LCDsetEntryMode(char inc, char shift)
{
	LCDwriteCommand(0x04 + inc*0x02 + shift*0x01, RS_LOW);
	delayms(1);
}

void LCDdispOnOff(char disp, char curs, char blink)
{
	LCDwriteCommand(0x08 + disp*0x04 + curs*0x02 + blink*0x01, RS_LOW);
	delayms(1);
}

void LCDshift(char disp, char right)
{
	LCDwriteCommand(0x10 + disp*0x08 + right*0x40, RS_LOW);
	delayms(1);
}

void LCDfunctionSet(char length, char lines, char font)
{
	LCDwriteCommand(0x20 + length*0x10 + lines*0x08 + font*0x04, RS_LOW);
	delayms(1);
}

void LCDsetCGaddr(char address)
{
	LCDwriteCommand(0x40 + address, RS_LOW);
	delayms(1);
}

void LCDsetDDaddr(char address)
{
	LCDwriteCommand(0x80 + address, RS_LOW);
	delayms(1);
}

void LCDwrite(int data)
{
	LCDwriteCommand(data, RS_HIGH);
	delayms(1);
}
